#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
智能名称生成器
基于上下文和语义生成更自然的混淆名称
"""

import hashlib
import random
from typing import Dict, List, Set, Optional
from enum import Enum


class SymbolType(Enum):
    """符号类型"""
    CLASS = "class"
    STRUCT = "struct"
    ENUM = "enum"
    PROTOCOL = "protocol"
    INTERFACE = "interface"
    METHOD = "method"
    FUNCTION = "function"
    PROPERTY = "property"
    FIELD = "field"
    CONSTANT = "constant"
    VARIABLE = "variable"
    UNKNOWN = "unknown"


class NamingStyle(Enum):
    """命名风格"""
    CAMEL_CASE = "camelCase"          # myVariable
    PASCAL_CASE = "PascalCase"        # MyClass
    SNAKE_CASE = "snake_case"         # my_variable
    SCREAMING_SNAKE = "SCREAMING_SNAKE"  # MY_CONSTANT


class SmartNameGenerator:
    """
    智能名称生成器

    特点：
    1. 上下文感知：根据符号类型生成合适的名称
    2. 词典支持：使用常见单词生成自然名称
    3. 风格一致：保持命名风格一致性
    4. 冲突避免：智能处理重名
    """

    # 常见英文单词库（用于生成自然的名称）
    NOUNS = [
        'data', 'item', 'info', 'value', 'result', 'context', 'state',
        'config', 'option', 'setting', 'manager', 'handler', 'service',
        'controller', 'helper', 'utility', 'cache', 'buffer', 'queue',
        'stack', 'list', 'map', 'set', 'tree', 'node', 'element',
        'record', 'entry', 'field', 'column', 'row', 'table', 'model',
        'view', 'layout', 'widget', 'component', 'module', 'package',
        'client', 'server', 'request', 'response', 'session', 'token',
        'key', 'lock', 'flag', 'status', 'type', 'kind', 'format'
    ]

    VERBS = [
        'get', 'set', 'add', 'remove', 'delete', 'update', 'create',
        'init', 'build', 'make', 'load', 'save', 'read', 'write',
        'open', 'close', 'start', 'stop', 'run', 'execute', 'process',
        'handle', 'manage', 'check', 'validate', 'verify', 'test',
        'convert', 'transform', 'parse', 'format', 'encode', 'decode',
        'send', 'receive', 'fetch', 'push', 'pull', 'sync', 'refresh',
        'clear', 'reset', 'clean', 'flush', 'release', 'dispose'
    ]

    ADJECTIVES = [
        'main', 'base', 'core', 'root', 'top', 'first', 'last',
        'next', 'prev', 'current', 'active', 'temp', 'local', 'global',
        'public', 'private', 'internal', 'external', 'static', 'dynamic',
        'fast', 'slow', 'old', 'new', 'raw', 'clean', 'dirty', 'safe',
        'valid', 'invalid', 'empty', 'full', 'ready', 'busy', 'free'
    ]

    def __init__(self, seed: Optional[int] = None):
        """
        初始化名称生成器

        Args:
            seed: 随机种子（用于可重现的混淆）
        """
        self.used_names: Set[str] = set()
        self.symbol_index: Dict[SymbolType, int] = {}
        self.seed = seed

        if seed is not None:
            random.seed(seed)

    def generate_name(
        self,
        original: str,
        symbol_type: SymbolType = SymbolType.UNKNOWN,
        context: Optional[str] = None,
        style: str = "hybrid"
    ) -> str:
        """
        生成混淆名称

        Args:
            original: 原始符号名
            symbol_type: 符号类型
            context: 上下文信息（如类名）
            style: 命名风格 (dictionary, random, hybrid)

        Returns:
            混淆后的名称
        """
        if style == "dictionary":
            return self._generate_dictionary_name(original, symbol_type)
        elif style == "random":
            return self._generate_random_name(original, symbol_type)
        else:  # hybrid
            return self._generate_hybrid_name(original, symbol_type, context)

    def _generate_dictionary_name(
        self,
        original: str,
        symbol_type: SymbolType
    ) -> str:
        """
        使用词典生成名称

        策略：
        - 类/结构：形容词 + 名词 (FastCache, MainHandler)
        - 方法/函数：动词 + 名词 (getData, processItem)
        - 属性/字段：形容词 + 名词 或 名词 (activeState, config)
        - 常量：全大写名词 (DATA_KEY, STATUS_FLAG)
        """
        # 使用原始名称的哈希来选择词汇（确保可重现）
        hash_value = int(hashlib.md5(original.encode()).hexdigest(), 16)

        if symbol_type in (SymbolType.CLASS, SymbolType.STRUCT, SymbolType.ENUM):
            # PascalCase: AdjectiveNoun
            adj = self.ADJECTIVES[hash_value % len(self.ADJECTIVES)]
            noun = self.NOUNS[(hash_value // 10) % len(self.NOUNS)]
            base_name = f"{adj.capitalize()}{noun.capitalize()}"

        elif symbol_type in (SymbolType.METHOD, SymbolType.FUNCTION):
            # camelCase: verbNoun
            verb = self.VERBS[hash_value % len(self.VERBS)]
            noun = self.NOUNS[(hash_value // 10) % len(self.NOUNS)]
            base_name = f"{verb}{noun.capitalize()}"

        elif symbol_type == SymbolType.CONSTANT:
            # SCREAMING_SNAKE_CASE
            noun1 = self.NOUNS[hash_value % len(self.NOUNS)]
            noun2 = self.NOUNS[(hash_value // 10) % len(self.NOUNS)]
            base_name = f"{noun1.upper()}_{noun2.upper()}"

        else:  # PROPERTY, FIELD, VARIABLE
            # camelCase: adjectiveNoun or noun
            if hash_value % 2 == 0:
                adj = self.ADJECTIVES[hash_value % len(self.ADJECTIVES)]
                noun = self.NOUNS[(hash_value // 10) % len(self.NOUNS)]
                base_name = f"{adj}{noun.capitalize()}"
            else:
                noun = self.NOUNS[hash_value % len(self.NOUNS)]
                base_name = noun

        # 处理冲突
        return self._resolve_conflict(base_name)

    def _generate_random_name(
        self,
        original: str,
        symbol_type: SymbolType
    ) -> str:
        """
        生成随机名称

        策略：使用原始名称的哈希生成短字符串
        """
        hash_value = hashlib.md5(original.encode()).hexdigest()[:8]

        if symbol_type in (SymbolType.CLASS, SymbolType.STRUCT):
            base_name = f"C{hash_value}"  # C + hash
        elif symbol_type in (SymbolType.METHOD, SymbolType.FUNCTION):
            base_name = f"m{hash_value}"  # m + hash
        elif symbol_type == SymbolType.CONSTANT:
            base_name = f"K_{hash_value.upper()}"  # K_ + HASH
        else:
            base_name = f"v{hash_value}"  # v + hash

        return self._resolve_conflict(base_name)

    def _generate_hybrid_name(
        self,
        original: str,
        symbol_type: SymbolType,
        context: Optional[str] = None
    ) -> str:
        """
        混合策略：结合词典和随机

        对于重要类型（类、接口）使用词典，
        对于局部变量使用随机
        """
        if symbol_type in (
            SymbolType.CLASS,
            SymbolType.STRUCT,
            SymbolType.ENUM,
            SymbolType.PROTOCOL,
            SymbolType.INTERFACE
        ):
            # 重要类型：使用词典
            return self._generate_dictionary_name(original, symbol_type)
        else:
            # 其他类型：70%词典，30%随机
            hash_val = int(hashlib.md5(original.encode()).hexdigest(), 16)
            if hash_val % 10 < 7:
                return self._generate_dictionary_name(original, symbol_type)
            else:
                return self._generate_random_name(original, symbol_type)

    def _resolve_conflict(self, base_name: str) -> str:
        """
        解决命名冲突

        如果名称已被使用，添加数字后缀
        """
        if base_name not in self.used_names:
            self.used_names.add(base_name)
            return base_name

        # 尝试添加数字后缀
        counter = 2
        while True:
            candidate = f"{base_name}{counter}"
            if candidate not in self.used_names:
                self.used_names.add(candidate)
                return candidate
            counter += 1

            # 防止无限循环
            if counter > 1000:
                # 退化到完全随机
                random_suffix = hashlib.md5(
                    f"{base_name}{counter}".encode()
                ).hexdigest()[:4]
                candidate = f"{base_name}_{random_suffix}"
                self.used_names.add(candidate)
                return candidate

    def detect_symbol_type(self, symbol: str, context: Optional[str] = None) -> SymbolType:
        """
        检测符号类型

        基于命名约定推断类型：
        - 全大写：常量 (MAX_VALUE)
        - 大写开头：类/结构 (MyClass)
        - 小写开头：方法/属性 (myMethod)
        """
        if not symbol:
            return SymbolType.UNKNOWN

        # 检查上下文提示
        if context:
            context_lower = context.lower()
            if 'class' in context_lower:
                return SymbolType.CLASS
            elif 'method' in context_lower or 'function' in context_lower:
                return SymbolType.METHOD
            elif 'property' in context_lower or 'field' in context_lower:
                return SymbolType.PROPERTY

        # 基于命名约定推断
        if symbol.isupper() and '_' in symbol:
            return SymbolType.CONSTANT
        elif symbol[0].isupper():
            return SymbolType.CLASS
        elif symbol.startswith('get') or symbol.startswith('set'):
            return SymbolType.METHOD
        else:
            return SymbolType.PROPERTY

    def generate_batch(
        self,
        symbols: List[str],
        symbol_types: Optional[Dict[str, SymbolType]] = None,
        style: str = "hybrid"
    ) -> Dict[str, str]:
        """
        批量生成映射

        Args:
            symbols: 符号列表
            symbol_types: 符号类型映射（可选）
            style: 命名风格

        Returns:
            符号映射字典
        """
        mapping = {}

        for symbol in symbols:
            # 确定符号类型
            if symbol_types and symbol in symbol_types:
                sym_type = symbol_types[symbol]
            else:
                sym_type = self.detect_symbol_type(symbol)

            # 生成名称
            obfuscated = self.generate_name(symbol, sym_type, style=style)
            mapping[symbol] = obfuscated

        return mapping

    def reset(self):
        """重置生成器状态"""
        self.used_names.clear()
        self.symbol_index.clear()
        if self.seed is not None:
            random.seed(self.seed)

    def get_statistics(self) -> Dict[str, int]:
        """获取生成统计"""
        return {
            'total_names': len(self.used_names),
            'unique_names': len(self.used_names)
        }